home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / umentiler / source / umentiler.c < prev   
C/C++ Source or Header  |  1995-12-31  |  21KB  |  927 lines

  1. /*************************************************************************
  2.  *
  3.  * Umentiler
  4.  *
  5.  * Copyright ©1995 Lee Kindness cs2lk@scms.rgu.ac.uk
  6.  *
  7.  * Read Umentiler.guide (from the main archive) for distribution details.
  8.  *
  9.  * Umentiler.c
  10.  */
  11.  
  12. /* Includes are kept in gst.c for gst compilation purposes */
  13. #include "gst.c"
  14.  
  15. extern struct ExecBase *SysBase;
  16. extern struct DosLibrary *DOSBase;
  17. extern struct LocaleBase *LocaleBase;
  18.  
  19. /* Revision information */
  20. #include "Umentiler_rev.h"
  21.  
  22. /* Version String */
  23. const char ver[] = VERSTAG;
  24.  
  25. /*
  26.  * Keep all 'global' vars in a locally allocated and 
  27.  * passed around structure => Gives pure, reentrant code.
  28.  */
  29. struct Vars
  30. {
  31.     ULONG              v_Tags_p;
  32.     ULONG              v_Tags_e;
  33.     ULONG              v_Tags_i;
  34.     struct Locale     *v_Locale;
  35.     struct LocaleBase *v_LocaleBase;
  36. };
  37.  
  38. /* Prototypes */
  39. STRPTR      strsistr      (STRPTR, STRPTR);
  40. VOID        AddC2Cmd      (STRPTR, char);
  41. VOID        MFPutC        (BPTR, char, BOOL);
  42. VOID        RepMarkers    (struct Vars *, STRPTR, BPTR, BOOL);
  43. VOID        HInsertion    (struct Vars *, BPTR, STRPTR, ULONG);
  44. VOID        HInsertCmd    (struct Vars *, BPTR, STRPTR);
  45. ULONG __asm LFFunc        (register __a0 struct Hook *,
  46.                            register __a2 struct Locale *,
  47.                            register __a1 char);
  48. VOID        HDateCmd      (struct Vars *, BPTR, STRPTR, STRPTR, 
  49.                            LONG, BOOL, BOOL, BOOL);
  50. VOID        HVersionCmd   (BPTR, STRPTR, BOOL, BOOL, BOOL, BOOL);
  51. VOID        HProgramCmd   (struct Vars *, BPTR, STRPTR, BOOL);
  52. VOID        HVarCmd       (BPTR, STRPTR, BOOL, BOOL, BOOL);
  53. VOID        HSetvarCmd    (STRPTR, STRPTR);
  54.  
  55. /* Template for all temp file names */
  56. #define TMP_TEMP "T:UXXXXXX.XXX"
  57.  
  58.  
  59. /*************************************************************************
  60.  * strsistr() - returns s if f occurs at the start of s. Case insensitive.
  61.  */
  62.  
  63. STRPTR strsistr(STRPTR s, STRPTR f)
  64. {
  65.     if( s && f )
  66.     {
  67.         BOOL match = TRUE;
  68.         for( ; *s && *f && match; ++s, ++f )
  69.             if( toupper(*s) != toupper(*f) )
  70.                 match = FALSE;
  71.         if( match )
  72.             return( s );
  73.         else
  74.             return( NULL );
  75.     } else
  76.         return( NULL ); 
  77. }
  78.  
  79.  
  80. /*************************************************************************
  81.  * AddC2Cmd() - Add a charcter to the command string
  82.  */
  83.  
  84. VOID AddC2Cmd(STRPTR cmd, char ch)
  85. {
  86.     STRPTR s;
  87.     /* Find the null */
  88.     s = strchr(cmd, '\0');
  89.     /* Add the char */
  90.     *s = ch;
  91.     /*
  92.      * ++s;
  93.      * *s = '\0'
  94.      *
  95.      * (no need, we MEMF_CLEARed it)
  96.      */
  97. }
  98.  
  99.  
  100. /*************************************************************************
  101.  * MFPutC() - Will FPutC if certain conditions.
  102.  */
  103.  
  104. VOID MFPutC(BPTR file, char ch, BOOL nolines)
  105. {
  106.     if( !(nolines && ch == '\n') )
  107.         FPutC(file, ch);
  108. }
  109.  
  110.  
  111. /*************************************************************************
  112.  * HInsertion() - Insert text into the file
  113.  */
  114.  
  115. /* Commands */
  116. #define TXT_INSERT "INSERT"
  117. #define CMD_INSERT 1
  118. #define TXT_DATE "DATE"
  119. #define CMD_DATE 2
  120. #define TXT_VERSION "VERSION"
  121. #define CMD_VERSION 3
  122. #define TXT_PROGRAM "PROGRAM"
  123. #define CMD_PROGRAM 4
  124. #define TXT_VAR "VAR"
  125. #define CMD_VAR 5
  126. #define TXT_SETVAR "SETVAR"
  127. #define CMD_SETVAR 6
  128.  
  129. /* And ReadArg() templates for each */
  130. #define TMP_INSERT "FILE/A"
  131. #define OPT_INSERT_FILE 0
  132. #define TMP_DATE "FROM/K,LF=LOCALEFORMAT/K,F=FORMAT/N/K,NY=NODAY/S,ND=NODATE/S,NT=NOTIME/S"
  133. #define OPT_DATE_FROM 0
  134. #define OPT_DATE_LOCALEFORMAT 1
  135. #define OPT_DATE_FORMAT 2
  136. #define OPT_DATE_NODAY 3
  137. #define OPT_DATE_NODATE 4
  138. #define OPT_DATE_NOTIME 5
  139. #define TMP_VERSION "FROM/A,F=FULL/S,NN=NONAME/S,NV=NOVER/S,ND=NODATE/S"
  140. #define OPT_VERSION_FROM 0
  141. #define OPT_VERSION_FULL 1
  142. #define OPT_VERSION_NONAME 2
  143. #define OPT_VERSION_NOVER 3
  144. #define OPT_VERSION_NODATE 4
  145. #define TMP_PROGRAM "NL=NOLINES/S,CMDLINE/A/F"
  146. #define OPT_PROGRAM_NOLINES 0
  147. #define OPT_PROGRAM_CMDLINE 1
  148. #define TMP_VAR "FROM/A,NL=NEWLINE/S,G=GLOBAL/S,L=LOCAL/S"
  149. #define OPT_VAR_FROM 0
  150. #define OPT_VAR_NEWLINE 1
  151. #define OPT_VAR_GLOBAL 2
  152. #define OPT_VAR_LOCAL 3
  153. #define TMP_SETVAR "NAME/A,TEXT/A/F"
  154. #define OPT_SETVAR_NAME 0
  155. #define OPT_SETVAR_TEXT 1
  156.  
  157. /* Maximum number of options */
  158. #define OPT_ALL_MAX (OPT_DATE_NOTIME + 1)
  159. #define NOARG "\n"
  160.  
  161. VOID HInsertion(struct Vars *vars, BPTR destf, STRPTR cmd, ULONG cmdsize)
  162. {
  163.     STRPTR s, arg, temp;
  164.     LONG cnum;
  165.     
  166.     /* Skip any initial white space */
  167.     cmd = stpblk(cmd);
  168.     
  169.     /* skip to the arguments */
  170.     if( arg = strpbrk(cmd, "\t ") )
  171.         arg = stpblk(arg);
  172.     else
  173.         arg = NOARG;
  174.     
  175.     /* What command ? */
  176.     if( s = strsistr(cmd, TXT_INSERT) )
  177.     {
  178.         cnum = CMD_INSERT;
  179.         temp = TMP_INSERT;
  180.     } else if( s = strsistr(cmd, TXT_DATE) )
  181.     {
  182.         cnum = CMD_DATE;
  183.         temp = TMP_DATE;
  184.     } else if( s = strsistr(cmd, TXT_VERSION) )
  185.     {
  186.         cnum = CMD_VERSION;
  187.         temp = TMP_VERSION;
  188.     } else if( s = strsistr(cmd, TXT_PROGRAM) )
  189.     {
  190.         cnum = CMD_PROGRAM;
  191.         temp = TMP_PROGRAM;
  192.     } else if( s = strsistr(cmd, TXT_VAR) )
  193.     {
  194.         cnum = CMD_VAR;
  195.         temp = TMP_VAR;
  196.     } else if( s = strsistr(cmd, TXT_SETVAR) )
  197.     {
  198.         cnum = CMD_SETVAR;
  199.         temp = TMP_SETVAR;
  200.     } else
  201.     {
  202.         PrintFault(ERROR_ACTION_NOT_KNOWN, cmd);
  203.         cnum = 0;
  204.         temp = NULL;
  205.         ++vars->v_Tags_i;
  206.     }
  207.     if( cnum && temp && arg )
  208.     {
  209.         struct RDArgs *rda;
  210.         
  211.         /* Add a newline to the end of cmd (for ReadArgs()) */
  212.         if( *cmd != '\n' )
  213.             AddC2Cmd(cmd, '\n');
  214.         
  215.         if( rda = AllocDosObject(DOS_RDARGS, NULL) )
  216.         {
  217.             STRPTR args[OPT_ALL_MAX];
  218.             
  219.             rda->RDA_DAList = NULL;
  220.             rda->RDA_Flags |= RDAF_NOPROMPT;
  221.             rda->RDA_Buffer = NULL;
  222.             rda->RDA_Source.CS_Buffer = arg;
  223.             rda->RDA_Source.CS_Length = strlen(arg);
  224.             rda->RDA_Source.CS_CurChr = 0;
  225.             
  226.             memset(&args, 0, (sizeof(STRPTR) * OPT_ALL_MAX));
  227.             
  228.             /* Parse argumesnts for the option */
  229.             if( ReadArgs(temp, (LONG *)&args, rda) ) 
  230.             {
  231.                 switch( cnum )
  232.                 {
  233.                     case CMD_INSERT :
  234.                         HInsertCmd(vars, destf, args[OPT_INSERT_FILE]);
  235.                         break;
  236.                         
  237.                     case CMD_VERSION :
  238.                         HVersionCmd(destf, args[OPT_VERSION_FROM],
  239.                                      (BOOL)args[OPT_VERSION_FULL],
  240.                                      (BOOL)args[OPT_VERSION_NONAME],
  241.                                      (BOOL)args[OPT_VERSION_NOVER],
  242.                                      (BOOL)args[OPT_VERSION_NODATE]);
  243.                         break;
  244.                         
  245.                     case CMD_PROGRAM :
  246.                         HProgramCmd(vars, destf, args[OPT_PROGRAM_CMDLINE],
  247.                                            (BOOL)args[OPT_PROGRAM_NOLINES]);
  248.                         break;
  249.                         
  250.                     case CMD_DATE :    
  251.                         HDateCmd(vars, destf, args[OPT_DATE_FROM],
  252.                                               args[OPT_DATE_LOCALEFORMAT],
  253.                                               args[OPT_DATE_FORMAT] ? *((LONG *)args[OPT_DATE_FORMAT]) : 0,
  254.                                         (BOOL)args[OPT_DATE_NODAY],
  255.                                         (BOOL)args[OPT_DATE_NODATE],
  256.                                         (BOOL)args[OPT_DATE_NOTIME]);
  257.                         break;
  258.                     
  259.                     case CMD_VAR :
  260.                         HVarCmd(destf, args[OPT_VAR_FROM],
  261.                                  (BOOL)args[OPT_VAR_NEWLINE],
  262.                                  (BOOL)args[OPT_VAR_GLOBAL],
  263.                                  (BOOL)args[OPT_VAR_LOCAL]);
  264.                         break;
  265.                     
  266.                     case CMD_SETVAR :
  267.                         HSetvarCmd(args[OPT_SETVAR_NAME],
  268.                                    args[OPT_SETVAR_TEXT]);
  269.                         break;
  270.                 }
  271.                 ++vars->v_Tags_p;
  272.                 FreeArgs(rda);
  273.             } else
  274.                 ++vars->v_Tags_i;
  275.             FreeDosObject(DOS_RDARGS, rda);
  276.         }
  277.     }
  278.     /* Clear cmd */
  279.     memset(cmd, 0, cmdsize);
  280. }
  281.  
  282.  
  283. /*************************************************************************
  284.  * HInsertCmd() - Handle the INSERT command.
  285.  */
  286.  
  287. VOID HInsertCmd(struct Vars *vars, BPTR destf, STRPTR from)
  288. {
  289.     /* paste a file
  290.      * We simply recurse, call RepMarkers()
  291.      */
  292.     RepMarkers(vars, from, destf, FALSE);
  293. }
  294.  
  295.  
  296. /*************************************************************************
  297.  * HVersionCmd() - Handle the VERSION command.
  298.  */
  299.  
  300. #define VERSION_CMD_1ST_PART "Version "
  301. #define VERSION_CMD_2ND_PART " FULL"
  302. #define VERBUF_SIZE 256
  303. #define STATE_NAME 0
  304. #define STATE_VERSION 1
  305. #define STATE_DATE 2
  306.  
  307. VOID HVersionCmd(BPTR destf, STRPTR from, BOOL full, BOOL noname, BOOL nover, BOOL nodate)
  308. {
  309.     STRPTR cmd;
  310.     
  311.     /* Alloc cmd */
  312.     if( cmd = AllocVec(strlen(VERSION_CMD_1ST_PART) +
  313.                        strlen(VERSION_CMD_2ND_PART) +
  314.                        strlen(from) + 1, 0) )
  315.     {
  316.         STRPTR tmpname;
  317.         
  318.         /* build the command line */
  319.         strcpy(cmd, VERSION_CMD_1ST_PART);
  320.         strcat(cmd, from);
  321.         strcat(cmd, VERSION_CMD_2ND_PART);
  322.         
  323.         /* Alloc tmpname */
  324.         if( tmpname = AllocVec(14, 0) )
  325.         {
  326.             strcpy(tmpname, TMP_TEMP);
  327.             mktemp(tmpname);
  328.             if( *tmpname != 0 )
  329.             {
  330.                 BPTR tf;
  331.                 
  332.                 /* Open temp file */
  333.                 if( tf = Open(tmpname, MODE_NEWFILE) )
  334.                 {
  335.                     BPTR inf;
  336.                     
  337.                     /* Open input file */
  338.                     if( inf = Open("NIL:", MODE_OLDFILE) )
  339.                     {
  340.                         if( SystemTags(cmd, SYS_Input,  inf,
  341.                                             SYS_Output, tf,
  342.                                             TAG_DONE) == 0 )
  343.                         {
  344.                             STRPTR verbuf;
  345.                             
  346.                             /* Version command successful, alloc verbuf */
  347.                             if( verbuf = AllocVec(VERBUF_SIZE, 0) )
  348.                             {
  349.                                 /* Seek to start */
  350.                                 Seek(tf, 0, OFFSET_BEGINNING);
  351.                                 
  352.                                 /* Read first line */
  353.                                 if( FGets(tf, verbuf, VERBUF_SIZE-1) )
  354.                                 {
  355.                                     STRPTR s;
  356.                                     LONG state = STATE_NAME;
  357.                                     
  358.                                     /* Remove trailing EOL */
  359.                                     if( s = strchr(verbuf, '\n') )
  360.                                         *s = '\0';
  361.                                     
  362.                                     if( !full )
  363.                                     {
  364.                                         for( s = verbuf; *s ; ++s )
  365.                                         {
  366.                                             switch( state )
  367.                                             {
  368.                                                 case STATE_NAME :
  369.                                                     if( isspace(*s) )
  370.                                                     {
  371.                                                         state++;
  372.                                                         if( (!noname && !nover) ||
  373.                                                             (!noname && nover && !nodate) )
  374.                                                             FPutC(destf, ' ');
  375.                                                         s = stpblk(s);
  376.                                                         --s;
  377.                                                     } else
  378.                                                     {
  379.                                                         if( !noname )
  380.                                                             FPutC(destf, *s);
  381.                                                     }
  382.                                                     break;
  383.                                                 
  384.                                                 case STATE_VERSION :
  385.                                                     if( isspace(*s) )
  386.                                                     {
  387.                                                         state++;
  388.                                                         if( !nover && !nodate )
  389.                                                             FPutC(destf, ' ');
  390.                                                         s = stpblk(s);
  391.                                                         --s;
  392.                                                     } else
  393.                                                     {
  394.                                                         if( !nover )
  395.                                                             FPutC(destf, *s);
  396.                                                     }
  397.                                                     break;
  398.                                                 
  399.                                                 case STATE_DATE :
  400.                                                     if( (*s != '(') && (*s != ')') && !nodate )
  401.                                                         FPutC(destf, *s);
  402.                                                     break;
  403.                                             }
  404.                                         }
  405.                                     } else
  406.                                         FPuts(destf, verbuf);
  407.                                 }
  408.                                 FreeVec(verbuf);
  409.                             }
  410.                         } else
  411.                             PrintFault(IoErr(), from);
  412.                         Close(inf);
  413.                     }
  414.                     Close(tf);
  415.                     DeleteFile(tmpname);
  416.                 }
  417.             }
  418.             FreeVec(tmpname);
  419.         }
  420.         FreeVec(cmd);
  421.     }
  422. }
  423.  
  424.  
  425. /*************************************************************************
  426.  * HProgramCmd() - Handle the PROGRAM command.
  427.  */
  428.  
  429.  
  430. VOID HProgramCmd(struct Vars *vars, BPTR destf, STRPTR cmdline, BOOL noline)
  431. {
  432.     STRPTR tmpname;
  433.     
  434.     /* Alloc tmpname */
  435.     if( tmpname = AllocVec(14, 0) )
  436.     {
  437.         strcpy(tmpname, TMP_TEMP);
  438.         mktemp(tmpname);
  439.         if( *tmpname != 0 )
  440.         {
  441.             BPTR tf;
  442.                 
  443.             /* Open temp file */
  444.             if( tf = Open(tmpname, MODE_NEWFILE) )
  445.             {
  446.                 if( SystemTags(cmdline, SYS_Output, tf, TAG_END) == 0 )
  447.                 {
  448.                     Close(tf);
  449.                     tf = 0;
  450.                     /* Recurse */
  451.                     RepMarkers(vars, tmpname, destf, noline);
  452.                 } else
  453.                     PrintFault(IoErr(), cmdline);
  454.  
  455.                 if( tf )
  456.                     Close(tf);
  457.                 DeleteFile(tmpname);
  458.             }
  459.         }
  460.         FreeVec(tmpname);
  461.     }
  462. }
  463.  
  464.  
  465. /*************************************************************************
  466.  * LFFunc() - Hook function for use in HDateCmd() by FormatDate().
  467.  */
  468.  
  469. /* 
  470.  * NOTE: no __saveds keyword, we dont need it and it would make us unpure
  471.  */
  472. ULONG __asm LFFunc(register __a0 struct Hook *hook,
  473.                    register __a2 struct Locale *locale,
  474.                    register __a1 char ch)
  475. {
  476.     /* hook->h_Data contains a BPTR of the file to output to */
  477.     if( ch )
  478.         FPutC((BPTR)hook->h_Data, ch);
  479.     return( TRUE );
  480. }
  481.  
  482.  
  483. /*************************************************************************
  484.  * HDateCmd() - Handle the DATE command.
  485.  */
  486.  
  487. VOID HDateCmd(struct Vars *vars, BPTR destf, STRPTR from, STRPTR localeformat, LONG format, 
  488.               BOOL noday, BOOL nodate, BOOL notime)
  489. {
  490.     struct DateStamp *ds = NULL;
  491.     
  492.     /* Get the datestamp */
  493.     if( from )
  494.     {
  495.         BPTR l;
  496.         
  497.         /* Read it from a file */
  498.         if( l = Lock(from, ACCESS_READ) )
  499.         {
  500.             struct FileInfoBlock *fib;
  501.             
  502.             /* Alloc fib */
  503.             if( fib = AllocDosObject(DOS_FIB, NULL) )
  504.             {
  505.                 if( Examine(l, fib) )
  506.                 {
  507.                     if( ds = AllocVec(sizeof(struct DateStamp), 0) )
  508.                     {
  509.                         /* Copy ds from the fib */
  510.                         memcpy(ds, &fib->fib_Date, sizeof(struct DateStamp));
  511.                     }
  512.                 }
  513.                 FreeDosObject(DOS_FIB, fib);
  514.             }
  515.             UnLock(l);
  516.         } else
  517.             PrintFault(IoErr(), from);
  518.     } else
  519.     {
  520.         if( ds = AllocVec(sizeof(struct DateStamp), 0) )
  521.             ds = DateStamp(ds);
  522.     }
  523.     if( ds )
  524.     {
  525.         /* Are we going to be locale or dos function based? */
  526.         if( localeformat && vars->v_Locale )
  527.         {
  528.             struct Hook *LFHook;
  529.             
  530.             if( LFHook = AllocVec(sizeof(struct Hook), MEMF_CLEAR) )
  531.             {
  532.                 LFHook->h_Entry    = (HOOKFUNC)LFFunc;
  533.                 
  534.                 /* Pass the file handle */
  535.                 LFHook->h_Data = (APTR)destf;
  536.                 
  537.                 FormatDate(vars->v_Locale, localeformat, ds, LFHook);
  538.                 FreeVec(LFHook);
  539.             }
  540.         } else
  541.         {
  542.             unsigned char daystr[LEN_DATSTRING], datestr[LEN_DATSTRING], timestr[LEN_DATSTRING];
  543.             struct DateTime *dt;
  544.             
  545.             if( dt = AllocVec(sizeof(struct DateTime), MEMF_CLEAR) )
  546.             {
  547.                 memcpy(&dt->dat_Stamp, ds, sizeof(struct DateStamp));
  548.                 dt->dat_Format = format;
  549.                 dt->dat_StrDay = (STRPTR)&daystr;
  550.                 dt->dat_StrDate = (STRPTR)&datestr;
  551.                 dt->dat_StrTime = (STRPTR)×tr;
  552.                 if( DateToStr(dt) )
  553.                 {
  554.                     if( !noday )
  555.                     {
  556.                         FPuts(destf, dt->dat_StrDay);
  557.                         if( !nodate || (nodate && !notime) )
  558.                             FPutC(destf, ' ');
  559.                     }
  560.                     
  561.                     if( !nodate )
  562.                     {
  563.                         FPuts(destf, dt->dat_StrDate);
  564.                         if( !notime )
  565.                             FPutC(destf, ' ');
  566.                     }
  567.                     
  568.                     if( !notime )
  569.                         FPuts(destf, dt->dat_StrTime);    
  570.                 }
  571.                 FreeVec(dt);
  572.             }
  573.         }
  574.         FreeVec(ds);
  575.     }
  576. }
  577.  
  578.  
  579. /*************************************************************************
  580.  * HVarCmd() - Handle the VAR command.
  581.  */
  582.  
  583. #define VAR_BUFFER_SIZE 512
  584.  
  585. VOID HVarCmd(BPTR destf, STRPTR from, BOOL newline, BOOL global, BOOL local)
  586. {
  587.     STRPTR buffer;
  588.     
  589.     /* Alloc buffer */
  590.     if( buffer = AllocVec(VAR_BUFFER_SIZE, 0) )
  591.     {
  592.         ULONG flags = LV_VAR;
  593.         
  594.         if( global )
  595.             flags |= GVF_GLOBAL_ONLY;
  596.         else if( local )
  597.             flags |= GVF_LOCAL_ONLY;
  598.         
  599.         if( GetVar(from, buffer, VAR_BUFFER_SIZE, flags) != -1 )
  600.         {
  601.             FPuts(destf, buffer);
  602.             if( newline )
  603.                 FPutC(destf, '\n');
  604.         } else
  605.             PrintFault(IoErr(), from);
  606.         FreeVec(buffer);
  607.     }
  608. }
  609.  
  610.  
  611. /*************************************************************************
  612.  * HSetvarCmd() - Handle the SETVAR command.
  613.  */
  614.  
  615. VOID HSetvarCmd(STRPTR name, STRPTR text)
  616. {
  617.     SetVar(name, text, -1, LV_VAR | GVF_LOCAL_ONLY);
  618. }
  619.  
  620.  
  621. /*************************************************************************
  622.  * RepMarkers() - Parse a file and replace 'stuff'
  623.  */
  624.  
  625. /* Command introducors and terminators */
  626. #define INTRODUCER_1 '/'
  627. #define INTRODUCER_2 '>'  /* INTRODUCER = "/>" */
  628. #define TERMINATOR_1 '<'
  629. #define TERMINATOR_2 '\\' /* TERMINATOR = "<\" */
  630. #define ESCAPE_CHAR  '!'
  631.  
  632. /* When read thru a line char by char we can by in any of these states */
  633. #define LEV_ESCAPED_2 -2
  634. #define LEV_ESCAPED_1 -1
  635. #define LEV_NONE 0
  636. #define LEV_1 1
  637. #define LEV_2 2
  638. #define LEV_3 3
  639.  
  640. #define BUFFER_SIZE 256
  641.  
  642. #define CMD_BUF_SIZE strlen(buffer)+2
  643.  
  644. VOID RepMarkers(struct Vars *vars, STRPTR source, BPTR destf, BOOL nolines)
  645. {
  646.     BPTR sourcef;
  647.     
  648.     /* Open source file */
  649.     if( sourcef = Open(source, MODE_OLDFILE) )
  650.     {
  651.         APTR buf;
  652.             
  653.         /* Alloc buf */
  654.         if( buf = AllocVec(BUFFER_SIZE, 0) )
  655.         {
  656.             APTR buffer;
  657.             
  658.             /* Go thru the source file, line by line */
  659.             while( buffer = FGets(sourcef, buf, BUFFER_SIZE-1) )
  660.             {
  661.                 STRPTR cmd;
  662.                 
  663.                 /* Alloc cmd buffer.
  664.                  * strlen(buffer)+2, 1 extra for the null and 1 more cause we add
  665.                  * on a '\n' in HInsertion()
  666.                  */
  667.                 if( cmd = AllocVec(CMD_BUF_SIZE, MEMF_CLEAR) )
  668.                 {
  669.                     register STRPTR s;
  670.                     register LONG level = LEV_NONE;
  671.                     /*
  672.                      * For each line we parse each character in a
  673.                      * state machine manner.
  674.                      */
  675.                     for( s = buffer; *s ; ++s )
  676.                     {
  677.                         switch( level )
  678.                         {
  679.                             case LEV_ESCAPED_1 :
  680.                                 switch( *s )
  681.                                 {
  682.                                     case INTRODUCER_1 :
  683.                                         level = LEV_ESCAPED_2;
  684.                                         break;
  685.                                     
  686.                                     case ESCAPE_CHAR :
  687.                                         level = LEV_ESCAPED_1;
  688.                                         FPutC(destf, (LONG)ESCAPE_CHAR);
  689.                                         break;
  690.                                     
  691.                                     default:
  692.                                         level = LEV_NONE;
  693.                                         FPutC(destf, (LONG)ESCAPE_CHAR);
  694.                                         MFPutC(destf, (LONG)*s, nolines);
  695.                                         break;
  696.                                 }
  697.                                 break;
  698.                                                             
  699.                             case LEV_ESCAPED_2 :
  700.                                 if( *s == INTRODUCER_2 )
  701.                                 {
  702.                                     FPutC(destf, (LONG)INTRODUCER_1);
  703.                                     FPutC(destf, (LONG)INTRODUCER_2);
  704.                                     ++vars->v_Tags_e;
  705.                                 } else
  706.                                 {
  707.                                     FPutC(destf, (LONG)ESCAPE_CHAR);
  708.                                     FPutC(destf, (LONG)INTRODUCER_1);
  709.                                     MFPutC(destf, (LONG)*s, nolines);
  710.                                 }
  711.                                 level = LEV_NONE;
  712.                                 break;
  713.                                 
  714.                             case LEV_NONE :
  715.                                 switch( *s )
  716.                                 {
  717.                                     case INTRODUCER_1 :
  718.                                         level = LEV_1;
  719.                                         break;
  720.                                     case ESCAPE_CHAR :
  721.                                         level = LEV_ESCAPED_1;
  722.                                         break;
  723.                                     default :
  724.                                         level = LEV_NONE;
  725.                                         MFPutC(destf, (LONG)*s, nolines);
  726.                                         break;
  727.                                 }
  728.                                 break;
  729.                                 
  730.                             case LEV_1 :
  731.                                 if( *s == INTRODUCER_2 )
  732.                                     level = LEV_2;
  733.                                 else
  734.                                 {
  735.                                     level = LEV_NONE;
  736.                                     FPutC(destf, (LONG)INTRODUCER_1);
  737.                                     MFPutC(destf, (LONG)*s, nolines);
  738.                                 }
  739.                                 break;
  740.                         
  741.                             case LEV_2 :
  742.                                 if( *s == TERMINATOR_1 )
  743.                                     level = LEV_3;
  744.                                 else
  745.                                     AddC2Cmd(cmd, *s);
  746.                                 break;
  747.                             
  748.                             case LEV_3 :
  749.                                 if( *s == TERMINATOR_2 )
  750.                                 {
  751.                                     level = LEV_NONE;
  752.                                     HInsertion(vars, destf, cmd, CMD_BUF_SIZE);
  753.                                 } else
  754.                                 {
  755.                                     level = LEV_2;
  756.                                     AddC2Cmd(cmd, TERMINATOR_1);
  757.                                     AddC2Cmd(cmd, *s);
  758.                                 }
  759.                                 break;
  760.                         }
  761.                     }
  762.                     /* Do insertion if cmd has something in it (ie non terminated cmd) */
  763.                     if( *cmd != '\0' )
  764.                     {
  765.                         HInsertion(vars, destf, cmd, CMD_BUF_SIZE);
  766.                         MFPutC(destf, '\n', nolines);
  767.                     }
  768.                     FreeVec(cmd);
  769.                 }
  770.             }                
  771.             FreeVec(buffer);
  772.         }
  773.         Close(sourcef);
  774.     } else
  775.         PrintFault(IoErr(), source);
  776. }
  777.  
  778.  
  779. /*************************************************************************
  780.  * main() - Ehhh... It's kinda ehhh...
  781.  */
  782.  
  783. int main( VOID )
  784. {
  785.     LONG rc = 10;
  786.     if( (((struct Library *)DOSBase)->lib_Version > 35) &&
  787.         (((struct Library *)SysBase)->lib_Version > 35) )
  788.     {
  789.         struct Vars *vars;
  790.         
  791.         /* Allocate var structure */
  792.         if( vars = AllocVec(sizeof(struct Vars), MEMF_CLEAR) )
  793.         {
  794.             struct RDArgs *rdargs;
  795.             #define TEMPLATE "SOURCE/A,DESTINATION,QUIET/S"
  796.             #define OPT_SOURCE 0
  797.             #define OPT_DEST 1
  798.             #define OPT_QUIET 2
  799.             #define OPT_MAX 3
  800.             STRPTR args[OPT_MAX] = {0, 0, 0};
  801.             #define ARG_SOURCE args[OPT_SOURCE]
  802.             STRPTR  ARG_DEST;
  803.             #define ARG_QUIET (BOOL)args[OPT_QUIET]
  804.         
  805.             /* Open Locale */
  806.             if( vars->v_LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library", 38) )
  807.                 vars->v_Locale = OpenLocale(NULL);
  808.             else
  809.                 vars->v_Locale = NULL;
  810.             LocaleBase = vars->v_LocaleBase;
  811.         
  812.             /* Parse arguments */
  813.             if (rdargs = ReadArgs(TEMPLATE, (LONG *)&args, NULL))
  814.             {
  815.                 BPTR srcl;
  816.                 
  817.                 ARG_DEST = args[OPT_DEST];
  818.                 
  819.                 /* Lock source */
  820.                 if( srcl = Lock(ARG_SOURCE, ACCESS_READ) )
  821.                 {
  822.                     BOOL makefilename = FALSE;
  823.                     BOOL destok = TRUE;
  824.                     
  825.                     if( ARG_DEST )
  826.                     {
  827.                         BPTR destl;
  828.                     
  829.                         /* Try to lock dest */
  830.                         if( destl = Lock(ARG_DEST, ACCESS_READ) )
  831.                         {
  832.                             /* Same file? */
  833.                             if( SameLock(srcl, destl) == LOCK_SAME )
  834.                             {
  835.                                 destok = FALSE;
  836.                                 SetIoErr(ERROR_OBJECT_EXISTS);
  837.                             }
  838.                             UnLock(destl);
  839.                         }
  840.                     } else
  841.                         makefilename = TRUE;
  842.                     
  843.                     if( makefilename )
  844.                     {
  845.                         /* Use a temp file */
  846.                         
  847.                         if( ARG_DEST = AllocVec(14, 0) )
  848.                         {
  849.                             strcpy(ARG_DEST, TMP_TEMP);
  850.                             mktemp(ARG_DEST);
  851.                             if( *ARG_DEST != 0 )
  852.                                 destok = TRUE;
  853.                         }
  854.                     }
  855.                     
  856.                     if( destok )
  857.                     {
  858.                         BPTR destf;
  859.                         if( destf = Open(ARG_DEST, MODE_NEWFILE) )
  860.                         {
  861.                             RepMarkers(vars, ARG_SOURCE, destf, FALSE);
  862.                             Close(destf);
  863.                             if( !ARG_QUIET )
  864.                             {
  865.                                 if( vars->v_Tags_p )
  866.                                     Printf("%ld tags processed\n", vars->v_Tags_p);
  867.                                 if( vars->v_Tags_e )
  868.                                     Printf("%ld tags escaped\n", vars->v_Tags_e);
  869.                                 if( vars->v_Tags_i )
  870.                                     Printf("%ld invalid tags\n", vars->v_Tags_i);
  871.                             }
  872.                             rc = 0;
  873.                         }
  874.                     }
  875.                     
  876.                     UnLock(srcl);
  877.                     
  878.                     if( makefilename )
  879.                     {
  880.                         if( rc == 0)
  881.                         {
  882.                             BPTR src;
  883.                             
  884.                             /* Copy ARG_DEST to ARG_SOURCE */
  885.                             
  886.                             if( src    = Open(ARG_DEST, MODE_OLDFILE) )
  887.                             {
  888.                                 BPTR dest;
  889.                                 
  890.                                 if( dest = Open(ARG_SOURCE, MODE_NEWFILE) )
  891.                                 {
  892.                                     LONG ch;
  893.                                     
  894.                                     for( ch = FGetC(src); ch != -1; ch = FGetC(src) )
  895.                                         FPutC(dest, ch);
  896.                                     
  897.                                     Close(dest);
  898.                                 }
  899.                                 Close(src);
  900.                             }
  901.                         }
  902.                         
  903.                         /* Delete the temp file */
  904.                         DeleteFile(ARG_DEST);
  905.                         
  906.                         /* Free name buffer */
  907.                         FreeVec(ARG_DEST);
  908.                     }
  909.  
  910.                 }
  911.                 FreeArgs(rdargs);
  912.             }
  913.         
  914.             if( vars->v_Locale )
  915.                 CloseLocale(vars->v_Locale);
  916.                 
  917.             if( vars->v_LocaleBase )
  918.                 CloseLibrary((struct Library *)vars->v_LocaleBase);
  919.             
  920.             FreeVec(vars);
  921.         }
  922.     }
  923.     if( rc )
  924.         PrintFault(IoErr(), "Umentiler");
  925.     return( rc );
  926. }
  927.